package sg.edu.nus.iss;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.jsp.jstl.core.Config;

import sg.edu.nus.iss.awsdynamodb.DynamoDB;
import sg.edu.nus.iss.awsdynamodb.LinearRegressionTable;
import sg.edu.nus.iss.awsdynamodb.MovingAverageTable;
import sg.edu.nus.iss.awsdynamodb.RelativeStrengthIndexTable;
import sg.edu.nus.iss.awsdynamodb.StochasticOscillatorTable;
import sg.edu.nus.iss.awsdynamodb.StockCodeTable;
import sg.edu.nus.iss.awsdynamodb.StockQuoteTable;
import sg.edu.nus.iss.stockex.*;
import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.PropertiesCredentials;
import com.amazonaws.services.dynamodb.AmazonDynamoDBClient;
import com.amazonaws.services.dynamodb.model.AttributeValue;
import com.amazonaws.services.dynamodb.model.ComparisonOperator;
import com.amazonaws.services.dynamodb.model.Condition;
import com.amazonaws.services.dynamodb.model.CreateTableRequest;
import com.amazonaws.services.dynamodb.model.DescribeTableRequest;
import com.amazonaws.services.dynamodb.model.KeySchema;
import com.amazonaws.services.dynamodb.model.KeySchemaElement;
import com.amazonaws.services.dynamodb.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodb.model.PutItemRequest;
import com.amazonaws.services.dynamodb.model.PutItemResult;
import com.amazonaws.services.dynamodb.model.ScanRequest;
import com.amazonaws.services.dynamodb.model.ScanResult;
import com.amazonaws.services.dynamodb.model.TableDescription;
import com.amazonaws.services.dynamodb.model.TableStatus;


public class JOB {
	private AmazonDynamoDBClient dynamoDB;
	private StockCodeTable stockCodeTable = new StockCodeTable();
	private StockQuoteTable stockQuoteTable = new StockQuoteTable();
	private LinearRegressionTable linearRegressionTable = new LinearRegressionTable();
	private StochasticOscillatorTable stochasticOscillatorTable = new StochasticOscillatorTable();
	private MovingAverageTable movingAverageTable = new MovingAverageTable();
	private RelativeStrengthIndexTable relativeStrengthIndexTable = new RelativeStrengthIndexTable();
	
	public static final String TABLE_NAME = "stock-quote2";
	
	public JOB(){
		super();
		try{
			dynamoDB = DynamoDB.client();
		}catch (Exception e) {
			e.printStackTrace();
			System.out.println("exception in init...");
		}
	}
	

    private  Map<String, AttributeValue> addStockQuoteItem(String[] quoteInfo)
    {
    	Map<String, AttributeValue> item = new HashMap<String, AttributeValue>();
    	if(!(quoteInfo.length == 15))
    	{
    		return null;
    	}
    	
    	return item;
    }
    
    public void addStockQuotesToDB(String dateStr)
    {
    	ArrayList<StockQuote> quoteList;
        
        try{
        	quoteList = StockQuoteUtil.getQuoteList(dateStr);
        }catch (Exception e) {
			// TODO: handle exception
        	e.printStackTrace();
        	quoteList = null;
        	return;
		}
        try {
        	if(quoteList==null & quoteList.size()<=0)
        	{return;}

            // Create a table with a primary key named 'name', which holds a string
        	stockQuoteTable.createTable();

            // Wait for it to become active
            DynamoDB.waitForTableToBecomeAvailable(TABLE_NAME);
            
            //Add stock quote
            for (StockQuote stockQuote : quoteList) {
				 Map<String,AttributeValue> item = stockQuoteTable.newItem(stockQuote);
				 PutItemRequest putItemRequest = new PutItemRequest(TABLE_NAME, item);
				 PutItemResult putItemResult = dynamoDB.putItem(putItemRequest);
		         System.out.println("Result: " + putItemResult);
			}
                      
           

        } catch (AmazonServiceException ase) {
            System.out.println("Caught an AmazonServiceException, which means your request made it "
                    + "to AWS, but was rejected with an error response for some reason.");
            System.out.println("Error Message:    " + ase.getMessage());
            System.out.println("HTTP Status Code: " + ase.getStatusCode());
            System.out.println("AWS Error Code:   " + ase.getErrorCode());
            System.out.println("Error Type:       " + ase.getErrorType());
            System.out.println("Request ID:       " + ase.getRequestId());
        } catch (AmazonClientException ace) {
            System.out.println("Caught an AmazonClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with AWS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message: " + ace.getMessage());
        }
    }
   
    public  ArrayList<StockQuote> getStockQuoteListFromDB()
    {
    	return stockQuoteTable.listItems();
    }
    
    public List<MovingAverage> getMovingAverage(String stockCode, Date date){
    	List<MovingAverage> maList = movingAverageTable.query(stockCode, Util.formatDate(date));
    	return maList;
    	
    }
    
    public List<StochasticOscillator> getScholasticOscillator(String stockCode, Date date){
    	List<StochasticOscillator> soList = stochasticOscillatorTable.query(stockCode, Util.formatDate(date));
    	return soList;
    	
    }
    
    public List<RelativeStrengthIndex> getRelativeStrengthIndex(String stockCode, Date date){
    	List<RelativeStrengthIndex> rsiList = relativeStrengthIndexTable.query(stockCode, Util.formatDate(date));
    	return rsiList;
    	
    }

    public LinearRegressionWithPoints getLinearRegression(String stockCode, Date date){
    	
    	LinearRegressionWithPoints linearRegressionWithPoints = new LinearRegressionWithPoints();
    	LinearRegression linearRegression = linearRegressionTable.query(stockCode, Util.formatDate(date));
    	if (linearRegression == null) return null;
    	
    	List<DateValuePair> pointsInLine = new ArrayList<DateValuePair>();
    	
    	Calendar cal = Calendar.getInstance();
    	for (int i = 1; i<= CONFIG.WINDOW_SIZE; i++){
    		cal.setTime(date);
    		cal.add(Calendar.DATE,-CONFIG.WINDOW_SIZE+1);
    		Date valueDate = cal.getTime();
    		double value = linearRegression.slope * i + linearRegression.getIntercept();
    		DateValuePair dv = new DateValuePair(valueDate, value, i);
    		pointsInLine.add(dv);
    	}
    	
    	linearRegressionWithPoints.setLinearRegression(linearRegression);
    	linearRegressionWithPoints.setPointsInLine(pointsInLine);
    	return linearRegressionWithPoints;
    	
    }
    
    public List<StockCode> getAllStockCodes(){
    List<StockCode> stockCodeList  = stockCodeTable.getStockCodes();
    Collections.sort(stockCodeList);
    return stockCodeList;
    }
    
    public List<StockQuote> getStock(String stockCode, String startDate, String endDate){
    	List<StockQuote> stockList = stockQuoteTable.query(stockCode, startDate, endDate);
    	return stockList;
    	
    }
    
}
